# -*- coding: utf-8 -*-
#
# Author:: Jonny
# Date:: 2022/4/24
import os
import random
import traceback
import uuid
from pathlib import Path
from time import sleep

from PIL import Image

from compat.common import is_windows, is_linux
from lib.tools import keep_tmp_images_clean
from submodules.common.lib.adb_driver import Device
from submodules.common.lib.datetime_ import get_timestamp
from compat.project_paths import project_path
from compat.project_paths import project_tmp_images_path
from obj import obj_bounds
from submodules.common.lib.image_ import img_cut

from submodules.common.lib.log_ import get_logger
from lib.image_ import is_image_match

logger = get_logger()


def init_screenshot_path():
    os.environ["screenshot_path"] = ""


def get_screenshot(suffix="", file_path=None):
    for i in range(100):
        if file_path == None:
            file_path = os.path.join(
                project_tmp_images_path,
                get_timestamp()
                + "-"
                + "screenshot"
                + "-"
                + suffix
                + "-"
                + str(uuid.uuid1())
                + ".png",
            )
        logger.info("file_path:%s" % file_path)

        cmd_tmp = f"adb exec-out screencap -p > {file_path}"

        try:
            r = os.popen(cmd_tmp)
            r.close()
            if is_linux():
                file_path = img_cut(
                    file_path, (0, 0, 1280, 720), image_path_out=file_path
                )
            break
        except Exception as e:
            logger.error(repr(e))
            logger.error(traceback.format_exc())
        sleep(1)

    logger.info("screenshot_file_path:%s" % file_path)
    return file_path


def swipe(x1, y1, x2, y2, time=50):
    cmd_tmp = f"adb shell input swipe {x1} {y1} {x2} {y2} {time}"
    logger.info(f"cmd_tmp:{cmd_tmp}")
    os.popen(cmd_tmp)


def swipe_by_bounds(x1, y1, x2, y2):
    # 擦除边界增加冗余
    # x2 = x2 + 10
    x2 = x2 + 200

    # # 横向
    # y1_tmp = y1
    # for i39 in range(1000):
    #     mohuzhi1 = random.uniform(0.8, 1.2)
    #     mohuzhi2 = random.uniform(0.8, 1.2)
    #     mohuzhi3 = random.uniform(0.8, 1.2)
    #     mohuzhi4 = random.uniform(0.8, 1.2)
    #
    #     swipe(x1 * mohuzhi1, y1_tmp * mohuzhi2, x2 * mohuzhi3, y1_tmp * mohuzhi4)
    #
    #     y1_tmp = y1_tmp + 20
    #
    #     if y1_tmp > y2:
    #         break
    #
    #     sleep(0.8)
    # 横向
    y1_tmp = y1
    for i39 in range(1000):
        mohuzhi1 = random.uniform(0.999, 1)
        mohuzhi2 = random.uniform(0.999, 1)
        mohuzhi3 = random.uniform(0.999, 1)
        mohuzhi4 = random.uniform(0.999, 1)

        swipe(x1 * mohuzhi1, y1_tmp * mohuzhi2, x2 * mohuzhi3, y1_tmp * mohuzhi4)

        y1_tmp = y1_tmp + 13

        if y1_tmp > y2:
            break

        # sleep(0.1)
        sleep(0.4)  # 非夜神增加等待時間


def click(x, y):
    cmd_tmp = f"adb shell input tap {x} {y}"
    os.popen(cmd_tmp)
    # sleep(0.5)


def click_by_bounds(x1, y1, x2, y2, step=None, timeout=None):
    # 区域内随机位置点击
    x = random.uniform(x1, x2)
    y = random.uniform(y1, y2)

    if timeout == None:
        if step == None:
            click(x, y)
        else:
            for x in range(x1, x2, step):
                for y in range(y1, y2, step):
                    click(x, y)
                    sleep(0.1)
                    # sleep(0.5)  # 逍遥在虚拟机比较卡增加等待时间
    else:
        swipe(x, y, x, y, timeout)

    sleep(random.uniform(0.6, 0.8))


def click_by_image(
    obj_info, obj_info_ref=None, timeout=None, is_reduce_noise=False, threshold=0.9
):
    try:
        keep_tmp_images_clean(1000)

        # 初始化screenshot_path
        try:
            os.environ["screenshot_path"]
        except Exception as e:
            os.environ["screenshot_path"] = ""

        # 获取或更新screenshot_path
        if os.environ["screenshot_path"] == "":
            os.environ["screenshot_path"] = get_screenshot()
        else:
            p = Path(os.environ["screenshot_path"])
            timestamp_screenshot_path = int(p.name[:14])
            timestamp = int(get_timestamp())
            if timestamp - timestamp_screenshot_path > 3:  # 过期时间：3秒
                os.environ["screenshot_path"] = get_screenshot()

        obj_path = os.path.join(project_path, "obj")

        if obj_info_ref is None:
            obj_info_ref = obj_info

        bounds_tuple = obj_info["bounds"]

        element_name_ref = obj_info_ref["name"]
        bounds_tuple_ref = obj_info_ref["bounds"]
        tmp_list_ref = element_name_ref.split("__")
        page_name_ref = tmp_list_ref[0]
        element_filename_ref = element_name_ref + ".png"
        target_img_path_ref = os.path.join(
            obj_path, page_name_ref, element_filename_ref
        )

        if os.path.exists(target_img_path_ref):
            pass
        else:
            # 首次使用，切图并保存
            tmp_list = element_name_ref.split("__")
            page_name = tmp_list[0]
            page_filename = tmp_list[1]
            image_path_in = os.path.join(obj_path, page_name, f"{page_filename}.png")
            image_path_out = os.path.join(
                obj_path, page_name, element_name_ref + ".png"
            )
            img_cut(
                image_path_in=image_path_in,
                image_path_out=image_path_out,
                bounds_tuple=bounds_tuple_ref,
            )

        is_match = is_image_match(
            img_path1=target_img_path_ref,
            img_path2=os.environ["screenshot_path"],
            bounds=bounds_tuple_ref,
            is_reduce_noise=is_reduce_noise,
            threshold=threshold,
        )
        if is_match:
            os.environ["screenshot_path"] = ""

            logger.info(obj_info["name"])
            click_by_bounds(*bounds_tuple, timeout=timeout)
            # sleep(0.5)  # 虚拟机中的逍遥比较卡 增加等待时间0.5
            return True
        else:
            return False
    except Exception as e:
        logger.error(repr(e))
        logger.error(traceback.format_exc())
        return False


def is_app_alive(package_name):
    res = os.popen(f'adb shell "ps -ef | grep {package_name}').readlines()
    logger.info(f"adb shell res:{res}")
    tmp_list = []
    for item in res:
        if "grep" in item:
            continue
        else:
            tmp_list.append(item)
    if len(tmp_list) > 0:
        return True
    else:
        return False


def is_app_focus(package_name):
    res = os.popen('adb shell "dumpsys window w|grep mFocusedApp"').read()
    logger.info(f"adb shell res:{res}")
    if package_name in res:
        return True
    else:
        return False


def get_current_activity(package_name):
    if is_windows():
        cmd_str = f"adb shell dumpsys activity | findstr mFocusedActivity"
    else:
        cmd_str = None
    res_str = os.popen(cmd_str).readlines()[0]
    list_tmp = res_str.strip().split(" ")[3].split("/")
    package_name = list_tmp[0]
    activity_name = list_tmp[1]
    return activity_name


def is_exsit(obj_info_ref, threshold=0.9, is_reduce_noise=False):
    # 初始化screenshot_path
    try:
        os.environ["screenshot_path"]
    except Exception as e:
        logger.error(repr(e))
        logger.error(traceback.format_exc())
        os.environ["screenshot_path"] = ""

    # 获取或更新screenshot_path
    if os.environ["screenshot_path"] == "":
        os.environ["screenshot_path"] = get_screenshot()
    else:
        p = Path(os.environ["screenshot_path"])
        timestamp_screenshot_path = int(p.name[:14])
        timestamp = int(get_timestamp())
        if timestamp - timestamp_screenshot_path > 3:  # 过期时间：3秒
            os.environ["screenshot_path"] = get_screenshot()

    obj_path = os.path.join(project_path, "obj")

    element_name_ref = obj_info_ref["name"]
    bounds_tuple_ref = obj_info_ref["bounds"]
    tmp_list_ref = element_name_ref.split("__")
    page_name_ref = tmp_list_ref[0]
    element_filename_ref = element_name_ref + ".png"
    target_img_path_ref = os.path.join(obj_path, page_name_ref, element_filename_ref)

    if os.path.exists(target_img_path_ref):
        pass
    else:
        # 首次使用，切图并保存
        tmp_list = element_name_ref.split("__")
        page_name = tmp_list[0]
        page_filename = tmp_list[1]
        image_path_in = os.path.join(obj_path, page_name, f"{page_filename}.png")
        image_path_out = os.path.join(obj_path, page_name, element_name_ref + ".png")
        from lib.image_ import img_cut

        img_cut(
            image_path_in=image_path_in,
            image_path_out=image_path_out,
            bounds_tuple=bounds_tuple_ref,
        )

    is_match = is_image_match(
        img_path1=target_img_path_ref,
        img_path2=os.environ["screenshot_path"],
        bounds=bounds_tuple_ref,
        is_reduce_noise=is_reduce_noise,
        threshold=threshold,
    )
    if is_match:
        logger.info(obj_info_ref["name"])
        return True
    else:
        return False


def input(text):
    cmd_tmp = f"adb shell input text {text}"
    os.popen(cmd_tmp)
    sleep(0.5)


def enter():
    cmd_tmp = f"adb shell input keyevent 66"
    os.popen(cmd_tmp)
    sleep(0.5)


def exec_event_log(event_log_path):
    event_log_processed = []
    f = open(event_log_path, "r")
    for line in f.readlines():
        line_list = line.strip().split(" ")

        line_list[0] = line_list[0][:-1]
        line_list[1] = int(line_list[1], 16)
        line_list[2] = int(line_list[2], 16)
        line_list[3] = int(line_list[3], 16)

        event_log_processed.append(line_list)

        cmd_tmp = f"adb shell sendevent {line_list[0]} {line_list[1]} {line_list[2]} {line_list[3]}"
        logger.info(f"cmd_tmp:{cmd_tmp}")
        os.popen(cmd_tmp)


def sendevent_syn_report(device_name="event5"):
    cmd_tmp = f"adb shell sendevent /dev/input/{device_name} 0 0 0"
    logger.info(f"cmd_tmp:{cmd_tmp}")
    os.popen(cmd_tmp)


def sendevent_touch_down(device_name="event5"):
    cmd_tmp = f"adb shell sendevent /dev/input/{device_name} 1 330 1"
    logger.info(f"cmd_tmp:{cmd_tmp}")
    os.popen(cmd_tmp)
    # cmd_tmp = f"adb shell sendevent /dev/input/{device_name} 3 48 5"
    # logger.info(f"cmd_tmp:{cmd_tmp}")
    # os.popen(cmd_tmp)
    sendevent_syn_report()


def sendevent_set_position(x, y, device_name="event5"):
    x = int(x)
    y = int(y)
    cmd_tmp = f"adb shell sendevent /dev/input/{device_name} 3 53 {x}"
    logger.info(f"cmd_tmp:{cmd_tmp}")
    os.popen(cmd_tmp)
    cmd_tmp = f"adb shell sendevent /dev/input/{device_name} 3 54 {y}"
    logger.info(f"cmd_tmp:{cmd_tmp}")
    os.popen(cmd_tmp)
    sendevent_syn_report()
    sleep(0.03)


def sendevent_touch_up(device_name="event5"):
    cmd_tmp = f"adb shell sendevent /dev/input/{device_name} 1 330 0"
    logger.info(f"cmd_tmp:{cmd_tmp}")
    os.popen(cmd_tmp)
    # cmd_tmp = f"adb shell sendevent /dev/input/{device_name} 3 48 0"
    # logger.info(f"cmd_tmp:{cmd_tmp}")
    # os.popen(cmd_tmp)
    sendevent_syn_report()


def swipe_by_bounds2(x1, y1, x2, y2, step_y):
    click(x1, y1)
    x1 = 250
    x2 = 1280 - x1

    sendevent_set_position(x1, y1)

    sendevent_touch_down()
    # step_x = 100
    # step_y = 20
    # count = 0
    # for i2 in range(0, (y2 - y1), step_y):
    #     y_tmp = y1 + i2
    #     y_tmp = random.uniform(0.98, 1) * y_tmp
    #     if count % 2 == 0:
    #         for i in range(0, 1280, step_x):
    #             if x1 + i > x2:
    #                 sendevent_set_position(x2, y_tmp)
    #                 break
    #             else:
    #                 sendevent_set_position(x1 + i, y_tmp)
    #     else:
    #         for i in range(0, 1280, step_x):
    #             if x2 - i < x1:
    #                 sendevent_set_position(x1, y_tmp)
    #                 break
    #             else:
    #                 sendevent_set_position(x2 - i, y_tmp)
    #     count += 1

    step_x = 500
    # step_y = 20
    for i in range(0, 10000, step_y):
        y_tmp = y1 + i
        # if y_tmp != y2:
        #     y_tmp = random.uniform(0.99, 1) * y_tmp
        if y_tmp > y2:
            y_tmp = y2

        for i2 in range(0, 10000, step_x):
            x_tmp = x1 + i2

            if x_tmp > x2:
                x_tmp = x2
            sendevent_set_position(x_tmp, y_tmp)

            if x_tmp == x2:
                break

        if y_tmp == y2:
            break

    sendevent_touch_up()


if __name__ == "__main__":

    def __test_swipe():
        swipe(700, 450, 100, 200, 2000)

    def __test_input():
        input("hahaha")
        enter()

    def __test_exec_event_log():
        from compat import project_paths

        event_log_path = os.path.join(project_paths.project_config_path, "event_log1")
        event_log_path = os.path.join(
            project_paths.project_config_path, "event_log_test"
        )

        exec_event_log(event_log_path)

    def __test_swipe_by_bounds2():
        bounds = (188, 300, 1132, 659)
        # bounds = obj_bounds.老君查岗页面_验证码区域
        # swipe_by_bounds2(*bounds)
        # bounds = obj_bounds.老君查岗页面_验证码区域
        swipe_by_bounds2(*bounds, 20)
        swipe_by_bounds2(*bounds, 20)

    def __test_swipe_by_bounds():
        bounds = (188, 300, 1132, 659)
        bounds = obj_bounds.老君查岗页面_验证码区域
        swipe_by_bounds(*bounds)

    def __test_start():
        from config import constants

        start(constants.PACKAGE_NAME_WENDAO, constants.ACTIVITY_NAME_WENDAO_MAIN)

    def __test_kill():
        from config import constants

        kill(constants.PACKAGE_NAME_WENDAO)

    def __test_is_app_alive():
        from config.constants import PACKAGE_NAME_WENDAO

        package_name = PACKAGE_NAME_WENDAO
        res = is_app_alive(package_name)
        print(res)

    def __test_is_app_focus():
        from config.constants import PACKAGE_NAME_WENDAO

        package_name = PACKAGE_NAME_WENDAO
        res = is_app_focus(package_name)
        print(res)

    __test_is_app_focus()
